//
//  UserInfoStore.swift
//  swiftim
//
//  Created by yangjian on 2023/7/21.
//

import Foundation

class UserInfoStore {
    
    var userInfoMap = [String : EMUserInfo]()
    let localLockObj = NSObject()
    
    var requestTempUsernameSet = Set<String>()
    let requestLockObj = NSObject()
    
    let workQueue = queue_bing(label: "UserInfoStore_queue")
    
    var delayRequestTimer : DispatchSourceTimer?
    
    static let share = UserInfoStore()
    init() {
        self._loadUserInfosFromDatabase()
    }
    
    
    func insert(userInfo : EMUserInfo){
        guard let username = userInfo.userId else {
            print("UserInfoStore::insert(userInfo:userinfo中username有问题")
            return
        }
        objc_sync_enter(localLockObj)
        self.userInfoMap[username] = userInfo
        UserInfoDBManager.share.insert(userInfos: [userInfo])
        objc_sync_exit(localLockObj)
    }
    
    func insert(userInfos : [EMUserInfo]) {
        objc_sync_enter(localLockObj)
        for userInfo in userInfos {
            guard let username = userInfo.userId else {
                print("UserInfoStore::insert(userInfos:userinfo中username有问题")
                continue
            }
            self.userInfoMap[username] = userInfo
        }
        UserInfoDBManager.share.insert(userInfos: userInfos)
        objc_sync_exit(localLockObj)
    }
    
    func fetchUserInfo(username : String) -> EMUserInfo {
        var userInfo = EMUserInfo()
        objc_sync_enter(localLockObj)
        userInfo = self.userInfoMap[username] ?? EMUserInfo()
        objc_sync_exit(localLockObj)
        return userInfo
    }
    
    
    //从服务器获取用户属性<会有延迟,专门设置的延迟,0.5s内还可以继续添加username,可合并成一个请求>
    func fetchUserInfosFromServer(usernames : [String]){
        print("请求了...")
        print(usernames)
        if usernames.isEmpty {
            return
        }
        var needRequest = false
        objc_sync_enter(requestLockObj)
        print("\(Date().timeIntervalSince1970)\n当前:[\(self.requestTempUsernameSet)]\n传入[\(usernames)]")
        if !self.requestTempUsernameSet.isSuperset(of:Set(usernames)) {
            self.requestTempUsernameSet.formUnion(Set(usernames))
            needRequest = true
        }
        objc_sync_exit(requestLockObj)
        
        if needRequest {
            //重新延时
            if self.delayRequestTimer != nil {
                self.delayRequestTimer?.cancel()
                self.delayRequestTimer = nil
            }
            let timer = DispatchSource.makeTimerSource(queue: self.workQueue)
            timer.setEventHandler(handler: {[unowned self] in
                print("开始request请求⚠️⚠️⚠️计时器请求")
                self._requestUserInfos()
            })
            timer.schedule(deadline: .now() + 1)
            timer.activate()
            self.delayRequestTimer = timer
        }
    }
}

extension UserInfoStore {
    
    private func _loadUserInfosFromDatabase(){
        objc_sync_enter(localLockObj)
        let uis = UserInfoDBManager.share.selectAll()
        for userInfo in uis {
            if let username = userInfo.userId {
                if username.count > 0 {
                    self.userInfoMap[username] = userInfo
                }
            }
        }
        objc_sync_exit(localLockObj)
        
        EMClient.shared().chatManager?.getConversationsFromServer()
        
    }
    
    private func _requestUserInfos(){
        self.delayRequestTimer?.cancel()
        self.delayRequestTimer = nil
        
        objc_sync_enter(requestLockObj)
        let requestUsernames = self.requestTempUsernameSet.prefix(100).base
        objc_sync_exit(requestLockObj)
        if requestUsernames.isEmpty {
            return
        }
//        print("开始request请求⚠️⚠️⚠️")
        EMClient.shared().userInfoManager?.fetchUserInfo(byId: Array(requestUsernames),completion: {[unowned self] responseUserInfoMap, error in
            guard let values = responseUserInfoMap?.values else {
                print("_requestUserInfos 这个请求没有获取到数据")
                if let error {
                    print("_requestUserInfos:error : \(error.code)-\(String(describing: error.errorDescription))")
                }
                return
            }
            var userInfos : [EMUserInfo] = []
            for userInfo in values {
                if userInfo is EMUserInfo {
                    userInfos.append(userInfo as! EMUserInfo)
                }
            }
            self.insert(userInfos: userInfos)
            objc_sync_enter(requestLockObj)
            self.requestTempUsernameSet.subtract(requestUsernames)
            if !self.requestTempUsernameSet.isEmpty {
                if self.delayRequestTimer == nil {
                    self._requestUserInfos()
                }
            }
            objc_sync_exit(requestLockObj)
            EMIMHelper.share.userinfoUpdateFinishSubject.onNext(Array(requestUsernames))
        })
    }
}
